bitkeeper revision 1.1159.1.398 (4190c2a3yFTT9r-Ede8ilkq-wZrXkg)
authorcl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>
Tue, 9 Nov 2004 13:14:11 +0000 (13:14 +0000)
committercl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>
Tue, 9 Nov 2004 13:14:11 +0000 (13:14 +0000)
Add focus to pirqs and interdomain evtchns.

xen/arch/x86/irq.c
xen/common/event_channel.c
xen/include/xen/event.h
xen/include/xen/irq.h
xen/include/xen/sched.h

index 32fa237747e4775f6fcfa458cc0907ec7a99be7f..0e4f28693819d3d914ba0cf7fca611935cf0c3bd 100644 (file)
@@ -188,22 +188,22 @@ typedef struct {
     u8 nr_guests;
     u8 in_flight;
     u8 shareable;
-    struct domain *guest[IRQ_MAX_GUESTS];
+    struct exec_domain *guest[IRQ_MAX_GUESTS];
 } irq_guest_action_t;
 
 static void __do_IRQ_guest(int irq)
 {
     irq_desc_t         *desc = &irq_desc[irq];
     irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
-    struct domain      *d;
+    struct exec_domain *ed;
     int                 i;
 
     for ( i = 0; i < action->nr_guests; i++ )
     {
-        d = action->guest[i];
-        if ( !test_and_set_bit(irq, &d->pirq_mask) )
+        ed = action->guest[i];
+        if ( !test_and_set_bit(irq, &ed->domain->pirq_mask) )
             action->in_flight++;
-        send_guest_pirq(d, irq);
+        send_guest_pirq(ed, irq);
     }
 }
 
@@ -235,8 +235,9 @@ int pirq_guest_unmask(struct domain *d)
     return 0;
 }
 
-int pirq_guest_bind(struct domain *d, int irq, int will_share)
+int pirq_guest_bind(struct exec_domain *ed, int irq, int will_share)
 {
+    struct domain      *d = ed->domain;
     irq_desc_t         *desc = &irq_desc[irq];
     irq_guest_action_t *action;
     unsigned long       flags;
@@ -296,7 +297,7 @@ int pirq_guest_bind(struct domain *d, int irq, int will_share)
         goto out;
     }
 
-    action->guest[action->nr_guests++] = d;
+    action->guest[action->nr_guests++] = ed;
 
  out:
     spin_unlock_irqrestore(&desc->lock, flags);
@@ -330,7 +331,7 @@ int pirq_guest_unbind(struct domain *d, int irq)
     else
     {
         i = 0;
-        while ( action->guest[i] != d )
+        while ( action->guest[i] && action->guest[i]->domain != d )
             i++;
         memmove(&action->guest[i], &action->guest[i+1], IRQ_MAX_GUESTS-i-1);
         action->nr_guests--;
index dd1c49b194670f5a11e75765441a74fe2b84f804..d8e7c9b9eba8b2837065f7a44376884f8c240c12 100644 (file)
@@ -96,6 +96,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
 {
 #define ERROR_EXIT(_errno) do { rc = (_errno); goto out; } while ( 0 )
     struct domain *d1, *d2;
+    struct exec_domain *ed1, *ed2;
     int            port1 = bind->port1, port2 = bind->port2;
     domid_t        dom1 = bind->dom1, dom2 = bind->dom2;
     long           rc = 0;
@@ -119,6 +120,9 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
         return -ESRCH;
     }
 
+    ed1 = d1->exec_domain[0];   /* XXX */
+    ed2 = d2->exec_domain[0];   /* XXX */
+
     /* Avoid deadlock by first acquiring lock of domain with smaller id. */
     if ( d1 < d2 )
     {
@@ -167,7 +171,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
         break;
 
     case ECS_INTERDOMAIN:
-        if ( d1->event_channel[port1].u.interdomain.remote_dom != d2 )
+        if ( d1->event_channel[port1].u.interdomain.remote_dom != ed2 )
             ERROR_EXIT(-EINVAL);
         if ( (d1->event_channel[port1].u.interdomain.remote_port != port2) &&
              (bind->port2 != 0) )
@@ -193,7 +197,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
         break;
 
     case ECS_INTERDOMAIN:
-        if ( d2->event_channel[port2].u.interdomain.remote_dom != d1 )
+        if ( d2->event_channel[port2].u.interdomain.remote_dom != ed1 )
             ERROR_EXIT(-EINVAL);
         if ( (d2->event_channel[port2].u.interdomain.remote_port != port1) &&
              (bind->port1 != 0) )
@@ -209,11 +213,11 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
      * Everything checked out okay -- bind <dom1,port1> to <dom2,port2>.
      */
 
-    d1->event_channel[port1].u.interdomain.remote_dom  = d2;
+    d1->event_channel[port1].u.interdomain.remote_dom  = ed2;
     d1->event_channel[port1].u.interdomain.remote_port = (u16)port2;
     d1->event_channel[port1].state                     = ECS_INTERDOMAIN;
     
-    d2->event_channel[port2].u.interdomain.remote_dom  = d1;
+    d2->event_channel[port2].u.interdomain.remote_dom  = ed1;
     d2->event_channel[port2].u.interdomain.remote_port = (u16)port1;
     d2->event_channel[port2].state                     = ECS_INTERDOMAIN;
 
@@ -284,7 +288,7 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
         goto out;
 
     d->pirq_to_evtchn[pirq] = port;
-    rc = pirq_guest_bind(d, pirq, 
+    rc = pirq_guest_bind(current, pirq, 
                          !!(bind->flags & BIND_PIRQ__WILL_SHARE));
     if ( rc != 0 )
     {
@@ -346,7 +350,7 @@ static long __evtchn_close(struct domain *d1, int port1)
     case ECS_INTERDOMAIN:
         if ( d2 == NULL )
         {
-            d2 = chn1[port1].u.interdomain.remote_dom;
+            d2 = chn1[port1].u.interdomain.remote_dom->domain;
 
             /* If we unlock d1 then we could lose d2. Must get a reference. */
             if ( unlikely(!get_domain(d2)) )
@@ -370,7 +374,7 @@ static long __evtchn_close(struct domain *d1, int port1)
                 goto again;
             }
         }
-        else if ( d2 != chn1[port1].u.interdomain.remote_dom )
+        else if ( d2 != chn1[port1].u.interdomain.remote_dom->domain )
         {
             rc = -EINVAL;
             goto out;
@@ -383,7 +387,7 @@ static long __evtchn_close(struct domain *d1, int port1)
             BUG();
         if ( chn2[port2].state != ECS_INTERDOMAIN )
             BUG();
-        if ( chn2[port2].u.interdomain.remote_dom != d1 )
+        if ( chn2[port2].u.interdomain.remote_dom->domain != d1 )
             BUG();
 
         chn2[port2].state = ECS_UNBOUND;
@@ -433,7 +437,8 @@ static long evtchn_close(evtchn_close_t *close)
 
 static long evtchn_send(int lport)
 {
-    struct domain *ld = current->domain, *rd;
+    struct domain *ld = current->domain;
+    struct exec_domain *rd;
     int            rport;
 
     spin_lock(&ld->event_channel_lock);
@@ -494,7 +499,8 @@ static long evtchn_status(evtchn_status_t *status)
         break;
     case ECS_INTERDOMAIN:
         status->status = EVTCHNSTAT_interdomain;
-        status->u.interdomain.dom  = chn[port].u.interdomain.remote_dom->id;
+        status->u.interdomain.dom  =
+            chn[port].u.interdomain.remote_dom->domain->id;
         status->u.interdomain.port = chn[port].u.interdomain.remote_port;
         break;
     case ECS_PIRQ:
index 517b22ed4d622e8d93cfabd5af655cc9260b6bca..168c28185dcaae4fa4b96dc1a0a8ddb28cd714fc 100644 (file)
@@ -20,9 +20,9 @@
  * may require explicit memory barriers.
  */
 
-static inline void evtchn_set_pending(struct domain *d, int port)
+static inline void evtchn_set_pending(struct exec_domain *ed, int port)
 {
-    struct exec_domain *ed = d->exec_domain[0];
+    struct domain *d = ed->domain;
     shared_info_t *s = d->shared_info;
     int            running;
 
@@ -57,8 +57,7 @@ static inline void evtchn_set_pending(struct domain *d, int port)
  */
 static inline void send_guest_virq(struct exec_domain *ed, int virq)
 {
-    struct domain *d = ed->domain;
-    evtchn_set_pending(d, d->virq_to_evtchn[virq]);
+    evtchn_set_pending(ed, ed->domain->virq_to_evtchn[virq]);
 }
 
 /*
@@ -66,9 +65,9 @@ static inline void send_guest_virq(struct exec_domain *ed, int virq)
  *  @d:        Domain to which physical IRQ should be sent
  *  @pirq:     Physical IRQ number
  */
-static inline void send_guest_pirq(struct domain *d, int pirq)
+static inline void send_guest_pirq(struct exec_domain *ed, int pirq)
 {
-    evtchn_set_pending(d, d->pirq_to_evtchn[pirq]);
+    evtchn_set_pending(ed, ed->domain->pirq_to_evtchn[pirq]);
 }
 
 #define event_pending(_d)                                     \
index 06233dddd24997613fe71a0b3c4d4cb0cf8c89d8..efd8f771251a3013f55d133acb04e4dd2f529316 100644 (file)
@@ -65,8 +65,9 @@ extern hw_irq_controller no_irq_type;
 extern void no_action(int cpl, void *dev_id, struct xen_regs *regs);
 
 struct domain;
+struct exec_domain;
 extern int pirq_guest_unmask(struct domain *p);
-extern int pirq_guest_bind(struct domain *p, int irq, int will_share);
+extern int pirq_guest_bind(struct exec_domain *p, int irq, int will_share);
 extern int pirq_guest_unbind(struct domain *p, int irq);
 extern int pirq_guest_bindable(int irq, int will_share);
 
index 17e58f6337a9931a74da12c3503713f78542991f..2c28a4a639a419e2a7d0d9a78feb89dfd50a1226 100644 (file)
@@ -42,8 +42,8 @@ typedef struct event_channel_st
             domid_t remote_domid;
         } __attribute__ ((packed)) unbound; /* state == ECS_UNBOUND */
         struct {
-            u16            remote_port;
-            struct domain *remote_dom;
+            u16                 remote_port;
+            struct exec_domain *remote_dom;
         } __attribute__ ((packed)) interdomain; /* state == ECS_INTERDOMAIN */
         u16 pirq; /* state == ECS_PIRQ */
         u16 virq; /* state == ECS_VIRQ */